home *** CD-ROM | disk | FTP | other *** search
- /*
- * AudioCompressor.cpp
- *
- * Copyright (C) Alberto Vigata - January 2000 - ultraflask@yahoo.com
- *
- * This file is part of FlasKMPEG, a free MPEG to MPEG/AVI converter
- *
- * FlasKMPEG is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * FlasKMPEG is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
- #include <windows.h>
- #include <mmsystem.h>
- #include <malloc.h>
- #include <winbase.h>
- #include <math.h>
-
- #include "AudioCompressor.h"
-
-
- CAudioCompressor::CAudioCompressor()
- {
- this->comp_lut= NULL;
- }
-
- CAudioCompressor::~CAudioCompressor()
- {
- if(comp_lut)
- free(comp_lut);
- }
-
- int CAudioCompressor::CreateCompressor()
- {
- TKnot myKnot;
- int i;
- //Initialize knots
- for(i=DEFAULT_KNOTS-1; i>=0; i--)
- {
- myKnot.in_dBLevel = -(float)(i+1)*((float)DB_RANGE/(float)(DEFAULT_KNOTS+1));
- myKnot.out_dBLevel = myKnot.in_dBLevel;
- knots.AddItem( &myKnot );
- }
- AdjustKnots(3);
- RenderCompressor();
-
- return 1;
- }
-
- int CAudioCompressor::AdjustKnots(int step)
- {
- int i;
- // Adjust out_DBLevels of every knot
- float free_range;
- float knot_step;
-
- if(step<0)
- step=0;
- if(step>=COMPRESSOR_STEPS)
- step=COMPRESSOR_STEPS-1;
-
- for(i=0; i<knots.GetCount(); i++)
- {
- // workout free dynamic range up to FS
- free_range = 0 - knots[i].in_dBLevel;
- // workout knot_step
- knot_step = free_range/(float)COMPRESSOR_STEPS;
-
- knots[i].out_dBLevel = knots[i].in_dBLevel + knot_step*step;
- }
- return 1;
- }
-
- int CAudioCompressor::RenderCompressor()
- {
- int x;
- if(comp_lut)
- {
- free(comp_lut);
- comp_lut=NULL;
- }
- comp_lut = (short *)malloc(INTEGER_COMPRESSOR_SIZE*sizeof(short));
- if(!comp_lut)
- return 0;
-
- #define DB_TO_LINEAR(x) ( 32767.0f *(float)pow(10, (float)x/20.0f ) )
- short in_start, in_end;
-
- // Render individual knots
- float end_dBLevel, start_dBLevel, stepLevel;
- TKnot this_knot, prev_knot;
- int steps, i;
-
- prev_knot.in_dBLevel = -DB_RANGE;
- prev_knot.out_dBLevel = -DB_RANGE;
-
- for(i=0; i<=knots.GetCount(); i++)
- {
- if(i<knots.GetCount())
- {
- this_knot = knots[i];
- }
- else{
- this_knot.in_dBLevel = 0;
- this_knot.out_dBLevel = 0;
- }
-
-
- start_dBLevel = prev_knot.out_dBLevel;
- end_dBLevel = this_knot.out_dBLevel;
-
- in_start =(short)DB_TO_LINEAR( prev_knot.in_dBLevel );
- in_end =(short)DB_TO_LINEAR( this_knot.in_dBLevel );
-
- steps = in_end - in_start;
- stepLevel = (end_dBLevel - start_dBLevel) / (float)steps;
-
- for(x=in_start; x<in_end; x++)
- {
- comp_lut[ x+32768]= (short)DB_TO_LINEAR( start_dBLevel );
- comp_lut[-x+32768]= -(short)DB_TO_LINEAR( start_dBLevel );
- start_dBLevel += stepLevel;
- }
-
- prev_knot = this_knot;
- }
- return 1;
- }
-
- int CAudioCompressor::Compress(short *data, int samples_count)
- {
- int i;
-
- short *lut=&comp_lut[32768];
-
- if(!data)
- return 0;
-
- for(i=0; i<samples_count; i++)
- data[i] = lut[ data[i] ];
- return 1;
-
- }
-